home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / net / bind-contrib.tar.gz / bind-contrib.tar / contrib / tic / poke_ns.c < prev    next >
C/C++ Source or Header  |  1996-10-25  |  4KB  |  185 lines

  1. char sccs_id[] = "@(#) poke_ns.c 1.4 92/08/31 @(#)";
  2.  
  3. /*
  4.  * simple front-end for sending signals to the bind process
  5.  * run setuid to root with appropriate group permission
  6.  * for your installation
  7.  */
  8.  
  9. /* Copyright (c) 1992 by Texas Internet Consulting
  10.  * This code may be freely copied and used so long as this
  11.  * copyright notice is attached.  This code may not be sold
  12.  * without the express written permission of Texas Internet Consulting.
  13.  * Texas Internet Consulting makes no warranty as to the correctness
  14.  * nor the applicability of this code for any purpose.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <sys/wait.h>
  21. #include <signal.h>
  22. #include <errno.h>
  23.  
  24. #define PIDFILE "/etc/named.pid"
  25. #define NAMED "/usr/etc/in.named"
  26. #define DB_DUMP "/usr/tmp/named_dump.db"
  27. #define DEBUG "/usr/tmp/named.run"
  28.  
  29. struct {
  30.     char *name;    /* command name */
  31.     int sig;    /* signal to send to bind */
  32. } commands[] = {
  33.     "restart",    SIGTERM,
  34.     "reload",    SIGHUP,
  35.     "debug",    SIGUSR1,
  36.     "nodebug",    SIGUSR2,
  37.     "dump",        SIGINT,
  38.     "terminate",    SIGTERM,
  39.     NULL,        0
  40. };
  41.  
  42. main(argc, argv)
  43. int argc;
  44. char **argv;
  45. {
  46.     FILE *fd;
  47.     int cmd, pid;
  48.     struct stat status;
  49.     void usage(), execute();
  50.     int lookup();
  51.     int uid, gid;
  52.  
  53.     if (argc != 2) {
  54.         usage();
  55.         exit(1);
  56.     }
  57.  
  58.     /* match one of the commands */
  59.     if ((cmd = lookup(argv[1])) == -1) {
  60.         fprintf(stderr, "command %s not found\n", argv[1]);
  61.         exit(1);
  62.     }
  63.  
  64.  
  65.     /* check permissions on /etc/named.pid */
  66.     if (stat(PIDFILE, &status) == -1) {
  67.         fprintf(stderr, "%s cannot stat\n", PIDFILE);
  68.         exit(2);
  69.     }
  70.     if (status.st_uid != 0) {
  71.         fprintf(stderr, "%s not owned by root\n", PIDFILE);
  72.         exit(2);
  73.     }
  74.     if (status.st_nlink > 1) {
  75.         fprintf(stderr, "%s has more than one link\n", PIDFILE);
  76.         exit(2);
  77.     }
  78.     if (status.st_mode&(S_IWGRP|S_IWOTH)) {
  79.         fprintf(stderr, "%s can be written by others\n", PIDFILE);
  80.         exit(2);
  81.     }
  82.  
  83.     /* if it is safe - then read pid */
  84.     if ((fd = fopen(PIDFILE, "r")) == NULL) {
  85.         fprintf(stderr, "%s cannot be read\n", PIDFILE);
  86.         exit(3);
  87.     }
  88.     if (fscanf(fd, "%d", &pid) != 1) {
  89.         fprintf(stderr, "%s does not contain an integer\n", PIDFILE);
  90.         exit(3);
  91.     }
  92.  
  93.     /* execute appropriate command */
  94.     execute(cmd, pid);
  95.  
  96.     /* change ownership to real user of debugging files */
  97.     uid = getuid();
  98.     gid = getgid();
  99.     chown(DB_DUMP, uid, gid);
  100.     chown(DEBUG, uid, gid);
  101.     exit(0);
  102. }
  103.  
  104. void
  105. usage()
  106. {
  107.     int i;
  108.  
  109.     fprintf(stderr, "usage: poke_ns ");
  110.     for (i=0; commands[i].name != NULL; i++) {
  111.         fprintf(stderr, commands[i].name);
  112.         if (commands[i+1].name != NULL) {
  113.             fprintf(stderr, " | ");
  114.         }
  115.         else {
  116.             fprintf(stderr, "\n");
  117.         }
  118.     }
  119. }
  120.     
  121. int
  122. lookup(cmd)
  123. char *cmd;
  124. {
  125.     int i;
  126.  
  127.     for (i=0; commands[i].name != NULL; i++) {
  128.         if (strcmp(commands[i].name, cmd) == 0) {
  129.             return i;
  130.         }
  131.     }
  132.     return -1;
  133. }
  134.  
  135. void
  136. execute(cmd, pid)
  137. int cmd;
  138. int pid;
  139. {
  140.     int newpid, wstat;
  141.  
  142.     /* some sanity checking on pid */
  143.     if (pid <= 2) {
  144.         fprintf(stderr, "pid (%d) must be greater than 2\n", pid);
  145.         exit(4);
  146.     }
  147.  
  148.     /* send the signal to the process */
  149.     if (kill(pid, commands[cmd].sig) == -1) {
  150.         /* let restart work if no named process is running */
  151.         if (!(cmd == 0 && errno == ESRCH)) {
  152.             fprintf(stderr, "signal failed\n");
  153.             exit(4);
  154.         }
  155.     }
  156.  
  157.     if (cmd != 0) {
  158.         return;
  159.     }
  160.     /* special case of "restart" */
  161.  
  162.     /* wait and be sure process is dead */
  163.     while (kill(pid, 0) != -1) {
  164.         sleep(1);
  165.     }
  166.     /* restart named */
  167.     newpid = fork();
  168.     if (newpid == -1) {
  169.         fprintf(stderr, "fork failed\n");
  170.         exit(5);
  171.     }
  172.     if (newpid == 0) { /* child */
  173.         execl(NAMED, "in.named", NULL);
  174.         /* only if execl failed */
  175.         fprintf(stderr, "execl failed\n");
  176.         exit(5);
  177.     }
  178.     /* parent */
  179.     wait (&wstat);
  180.     if (WEXITSTATUS(wstat) != 0) {
  181.         exit(5);
  182.     }
  183.     return;
  184. }
  185.